package com.whpost.service.tools;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.client.j2se.MatrixToImageWriter;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class BarcodeGenerator {
    // 定义Excel文件路径
    private static final String EXCEL_FILE_PATH = "D:\\条形码763.xlsx";
    // 定义保存条形码图片的目录
    private static final String SAVE_DIR = "D:\\条形码763";
    // 定义图片宽度（像素）
    private static final int WIDTH = 300;
    // 定义图片高度（像素）
    private static final int HEIGHT = 100;
    // 定义边距大小（像素）
    private static final int MARGIN = 20;

    public static void main(String[] args) {
        try {
            // 确保保存目录存在
            createSaveDirectory();

            // 读取Excel文件中J列的数据（索引为9）
            List<String> barcodeDataList = readColumnFromExcel(0);

            // 为每个数据生成条形码
            int successCount = 0;
            for (String data : barcodeDataList) {
                if (data != null && !data.trim().isEmpty()) {
                    generateBarcodeWithMargin(data.trim(), WIDTH, HEIGHT);
                    successCount++;
                }
            }

            System.out.printf("批量生成条形码完成！共处理 %d 条数据，成功生成 %d 张图片%n",
                    barcodeDataList.size(), successCount);
        } catch (Exception e) {
            System.err.println("处理过程中出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 从Excel文件中读取指定列的数据
     */
    private static List<String> readColumnFromExcel(int columnIndex) {
        List<String> columnData = new ArrayList<>();

        // 使用EasyExcel读取Excel文件
        EasyExcel.read(EXCEL_FILE_PATH, new AnalysisEventListener<Map<Integer, String>>() {
            @Override
            public void invoke(Map<Integer, String> rowData, AnalysisContext context) {
                // 获取指定列的数据
                String cellValue = rowData.get(columnIndex);
                columnData.add(cellValue);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                System.out.printf("Excel文件读取完成，共读取 %d 行数据%n", columnData.size());
            }
        }).sheet().doRead();

        return columnData;
    }

    /**
     * 生成带边距的条形码并保存为图片文件
     */
    public static void generateBarcodeWithMargin(String data, int width, int height) throws Exception {
        // 计算实际条形码区域大小
        int barcodeWidth = width - 2 * MARGIN;
        int barcodeHeight = height - 2 * MARGIN;

        if (barcodeWidth <= 0 || barcodeHeight <= 0) {
            throw new IllegalArgumentException("边距过大，导致条形码区域不足");
        }

        // 生成条形码矩阵（不含边距）
        BitMatrix barcodeMatrix = new MultiFormatWriter().encode(
                data, BarcodeFormat.CODE_128, barcodeWidth, barcodeHeight);

        // 创建带边距的BitMatrix
        BitMatrix matrixWithMargin = new BitMatrix(width, height);

        // 将条形码矩阵复制到带边距的矩阵中
        for (int x = 0; x < barcodeWidth; x++) {
            for (int y = 0; y < barcodeHeight; y++) {
                if (barcodeMatrix.get(x, y)) {
                    matrixWithMargin.set(x + MARGIN, y + MARGIN);
                }
            }
        }

        // 生成安全的文件名
        String fileName = data.replaceAll("[^a-zA-Z0-9]", "_") + ".png";
        Path path = Paths.get(SAVE_DIR, fileName);

        // 保存图片
        MatrixToImageWriter.writeToPath(matrixWithMargin, "PNG", path);
        System.out.println("已生成: " + path);
    }

    /**
     * 确保保存目录存在
     */
    private static void createSaveDirectory() throws IOException {
        Path dirPath = Paths.get(SAVE_DIR);
        if (!Files.exists(dirPath)) {
            Files.createDirectories(dirPath);
            System.out.println("已创建保存目录: " + SAVE_DIR);
        }
    }
}    